goto open_failed;
}
+
retry:
/* Set up store connection and watch. */
h = xs_daemon_open();
} else goto open_failed;
}
- ret = add_blockdevice_probe_watch(h, "Domain-0");
- if (ret != 0) {
+ ret = setup_probe_watch(h);
+ if (ret < 0) {
DPRINTF("Failed adding device probewatch\n");
- if (count < MAX_ATTEMPTS) {
- count++;
- sleep(2);
- xs_daemon_close(h);
- goto retry;
- } else goto open_failed;
+ xs_daemon_close(h);
+ goto open_failed;
+ } else {
+ DPRINTF("Added probe %s\n",
+ (ret ? "ASYNCHRONOUSLY":"SYNCHRONOUSLY"));
}
ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE );
#define CTLMSG_PID_RSP 10
/* xenstore/xenbus: */
-extern int add_blockdevice_probe_watch(struct xs_handle *h,
- const char *domname);
+#define DOMNAME "Domain-0"
+int setup_probe_watch(struct xs_handle *h);
int xs_fire_next_watch(struct xs_handle *h);
*are created, we initalise the state and attach a disk.
*/
-int add_blockdevice_probe_watch(struct xs_handle *h, const char *domname)
+int add_blockdevice_probe_watch(struct xs_handle *h, const char *domid)
{
- char *domid, *path;
+ char *path;
struct xenbus_watch *vbd_watch;
int er;
- domid = get_dom_domid(h, domname);
-
- DPRINTF("%s: %s\n",
- domname, (domid != NULL) ? domid : "[ not found! ]");
-
asprintf(&path, "/local/domain/%s/backend/tap", domid);
if (path == NULL)
return -ENOMEM;
}
return 0;
}
+
+/*
+ *Asynch callback to check for /local/domain/<DOMID>/name
+ */
+void check_dom(struct xs_handle *h, struct xenbus_watch *w,
+ const char *bepath_im) {
+ char *domid = NULL;
+
+ domid = get_dom_domid(h);
+ if (domid) {
+ add_blockdevice_probe_watch(h, domid);
+ free(domid);
+ unregister_xenbus_watch(h, w);
+ }
+ return;
+}
+
+/*
+ *We must wait for xend to register /local/domain/<DOMID>
+ */
+int watch_for_domid(struct xs_handle *h)
+{
+ struct xenbus_watch *domid_watch;
+ char *path = NULL;
+ int er;
+
+ asprintf(&path, "/local/domain");
+ if (path == NULL)
+ return -ENOMEM;
+
+ domid_watch = (struct xenbus_watch *)malloc(sizeof(struct xenbus_watch));
+ if (!domid_watch) {
+ DPRINTF("ERROR: unable to malloc domid_watch [%s]\n", path);
+ return -EINVAL;
+ }
+ domid_watch->node = path;
+ domid_watch->callback = check_dom;
+ er = register_xenbus_watch(h, domid_watch);
+ if (er == 0) {
+ DPRINTF("ERROR: adding vbd probe watch %s\n", path);
+ return -EINVAL;
+ }
+ if (path == NULL)
+ return -ENOMEM;
+ return 1;
+}
+
+int setup_probe_watch(struct xs_handle *h)
+{
+ char *domid = NULL, *path;
+ int ret;
+
+ domid = get_dom_domid(h);
+
+ if (!domid) {
+ /*Asynchronous path*/
+ ret = watch_for_domid(h);
+ goto finish;
+ } else {
+ /*Synchronous path*/
+ ret = add_blockdevice_probe_watch(h, domid);
+ free(domid);
+ }
+ finish:
+ return ret;
+}
* This assumes that the domain name we are looking for is unique.
* Name parameter Domain-0
*/
-char *get_dom_domid(struct xs_handle *h, const char *name)
+char *get_dom_domid(struct xs_handle *h)
{
char **e, *val, *domid = NULL;
unsigned int num, len;
if (val == NULL)
continue;
- if (strcmp(val, name) == 0) {
+ if (strcmp(val, DOMNAME) == 0) {
/* match! */
asprintf(&path, "/local/domain/%s/domid", e[i]);
domid = xs_read(h, xth, path, &len);
int xs_printf(struct xs_handle *h, const char *dir, const char *node,
const char *fmt, ...);
int xs_exists(struct xs_handle *h, const char *path);
-char *get_dom_domid(struct xs_handle *h, const char *name);
+char *get_dom_domid(struct xs_handle *h);
int convert_dev_name_to_num(char *name);
int register_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch);
int unregister_xenbus_watch(struct xs_handle *h, struct xenbus_watch *watch);